home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Archives / Timing / Uhr.lha / Uhr / Uhr.c < prev    next >
C/C++ Source or Header  |  1993-04-05  |  16KB  |  479 lines

  1. /*
  2.  *  Uhr.c
  3.  *
  4.  *  Author: Stefan Sticht
  5.  *
  6.  *  Copyright: source is public domain, no copyright
  7.  *
  8.  *  Version history:
  9.  *
  10.  *  V0.01   initial release
  11.  *  V0.02   using now cback.o
  12.  *  V0.03   RMBTRAP flag set
  13.  *  V0.04   added LockIBase before looking at IntuitionBase
  14.  *          (thanks to Holger Gzella for bug report),
  15.  *          added screen title
  16.  *  V0.05   structure for timerequest is now in MEMF_PUBLIC
  17.  *          (thanks to Holger Gzella)
  18.  *          now using CreateMsgPort() from exec.library instead of CreatePort() from amiga.lib
  19.  *  V0.06   changed LockPubScreen("Workbench") to LockPubScreen(NULL)
  20.  *          now using CreateIORequest(); using WaitIO() instead of Wait() after AbortIO()
  21.  *          removed LockIBase(), redefined SAS/C chkabort() to prevent CTRL/C trapping
  22.  *  V0.07 14 Sep 1991 small changes to reduce size
  23.  *  V1.00 13 May 1992 mow uses locale.library's FormatDate()
  24.  *  V1.01 19 Sep 1992 small changes, reduced size
  25.  *  V1.02 24 Sep 1992 added SPACE option
  26.  *  V1.03 19 Mar 1993 recompiled with SAS/C 6.2
  27.  */
  28.  
  29. #define VERSION "1.03"
  30.  
  31. #include <stdarg.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <devices/timer.h>
  35. #include <exec/memory.h>
  36. #include <intuition/intuitionbase.h>
  37. #include <libraries/locale.h>
  38. #include <workbench/icon.h>
  39. #include <workbench/startup.h>
  40. #include <clib/alib_protos.h>
  41. #include <clib/dos_protos.h>
  42. #include <clib/exec_protos.h>
  43. #include <clib/graphics_protos.h>
  44. #include <clib/icon_protos.h>
  45. #include <clib/intuition_protos.h>
  46. #include <clib/locale_protos.h>
  47. #include <pragmas/dos_pragmas.h>
  48. #include <pragmas/exec_sysbase_pragmas.h>
  49. #include <pragmas/graphics_pragmas.h>
  50. #include <pragmas/icon_pragmas.h>
  51. #include <pragmas/intuition_pragmas.h>
  52. #include <pragmas/locale_pragmas.h>
  53.  
  54. /*
  55.  *  prototypes
  56.  */
  57. long __stdargs request(char *title, char *gadgets, char *text, ...);
  58. struct Library __regargs *myopenlibrary(char *name, unsigned long version);
  59. void __regargs getmessages(struct Window *win);
  60. void __saveds __asm putcharfunc(register __a0 struct Hook *h, register __a2 void *object, register __a1 char c);
  61.  
  62. /*
  63.  *  global data
  64.  */
  65. #define PROGRAMTITLE    "Uhr"
  66. #define TITLE           PROGRAMTITLE " " VERSION " © Stefan Sticht"
  67.  
  68. #define MSG_ERROR_LIBRARY   "Couldn't open %s (V%ld)!"
  69. #define MSG_ERROR_OPENPORT  "Couldn't open message port!"
  70. #define MSG_ATTENTION       PROGRAMTITLE ":"
  71. #define RESUME_GADGETS      "Resume"
  72. #define RETRY_GADGETS       "Retry|Cancel"
  73.  
  74. #ifdef __SASC
  75. extern struct WBStartup *WBenchMsg;
  76. extern struct Library *DOSBase;
  77. extern struct Library *SysBase;
  78. #endif
  79.  
  80. #define BUFFERSIZE 100
  81. char buffer[BUFFERSIZE];
  82.  
  83. struct Hook putcharhook = {
  84.     {NULL, NULL},
  85.     (unsigned long (*)())putcharfunc,
  86.     NULL,
  87.     buffer
  88.     };
  89.  
  90. #define TITLE_OFFSET 7
  91. static char version[] ="\0$VER: " TITLE;
  92.  
  93. short bufferpos;
  94. struct DateStamp datestamp;
  95. struct Library *GfxBase;
  96. struct Library *LocaleBase;
  97. struct Locale *locale;
  98. struct IntuitionBase *IntuitionBase;
  99. struct timerequest *timereq;
  100. struct MsgPort *timerport;
  101.  
  102. unsigned long updateseconds = 1;
  103. unsigned long updatemicros  = 0;
  104. long priority = -1;
  105. long space = 20;
  106.  
  107. #define OPTION_FORMAT           "FORMAT"
  108. #define OPTION_UPDATESECONDS    "UPDATESECONDS"
  109. #define OPTION_UPDATEMICROS     "UPDATEMICROS"
  110. #define OPTION_LEFT             "LEFT"
  111. #define OPTION_TOP              "TOP"
  112. #define OPTION_WINDOWTOFRONT    "WINDOWTOFRONT"
  113. #define OPTION_PRIORITY         "PRIORITY"
  114. #define OPTION_PUBSCREEN        "PUBSCREEN"
  115. #define OPTION_SPACE            "SPACE"
  116. #define TEMPLATE OPTION_FORMAT "/K," "S=" OPTION_UPDATESECONDS "/K/N," "M=" OPTION_UPDATEMICROS "/K/N,"\
  117.                  OPTION_LEFT "/K/N," OPTION_TOP "/K/N," "WTF=" OPTION_WINDOWTOFRONT "/S,"\
  118.                  "PRI=" OPTION_PRIORITY "/K/N," OPTION_PUBSCREEN "/K," OPTION_SPACE "/K/N"
  119. #define OPTN_FORMAT             0
  120. #define OPTN_UPDATESECONDS      1
  121. #define OPTN_UPDATEMICROS       2
  122. #define OPTN_LEFT               3
  123. #define OPTN_TOP                4
  124. #define OPTN_WINDOWTOFRONT      5
  125. #define OPTN_PRIORITY           6
  126. #define OPTN_PUBSCREEN          7
  127. #define OPTN_SPACE              8
  128. #define OPTN_COUNT              9
  129. long options[OPTN_COUNT];
  130.  
  131. #define FORMAT          (options[OPTN_FORMAT])
  132. #define WINDOWTOFRONT   (options[OPTN_WINDOWTOFRONT])
  133. #define PUBSCREEN       (options[OPTN_PUBSCREEN])
  134.  
  135. /*
  136.  *  functions
  137.  */
  138.  
  139. /*
  140.  *  request(): a glue routine to EasyRequest as simple as printf plus
  141.  *             titlestring, gadgettexts
  142.  *
  143.  *  Input: char *title:         pointer to the title of the requester
  144.  *         char *gadgets:       pointer to gadgettext
  145.  *         char *text:          text displayed in requester
  146.  *
  147.  *  Result: same as EasyrequestArgs()
  148.  *
  149.  * !!! for more info see EasyRequestArgs() in Autodocs/intuition.doc !!!
  150.  */
  151. long __stdargs request(char *title, char *gadgets, char *text, ...)
  152. {
  153.     /*
  154.      *  structure textreq only needed in this function, so hide it here
  155.      *  must be static, in order to be initialized only once
  156.      */
  157.     long rc = 0;
  158.     struct EasyStruct textreq = {
  159.         sizeof (struct EasyStruct), /* ULONG es_StructSize      */
  160.         0l,                         /* ULONG es_Flags           */
  161.         NULL,                       /* UBYTE *es_Title          */
  162.         NULL,                       /* UBYTE *es_TextFormat     */
  163.         NULL,                       /* UBYTE *es_GadgetFormat   */
  164.         };
  165.     struct Process *process;
  166.     struct Window *win;
  167.     va_list ap;
  168.  
  169.     /*
  170.      *  get start of variable arguments
  171.      */
  172.     va_start(ap, text);
  173.  
  174.     if (process = (struct Process *)FindTask(NULL)) {
  175.         if ((long)(win = process->pr_WindowPtr) != -1) {
  176.  
  177.             /*
  178.              *  update textreq
  179.              */
  180.             textreq.es_Title = (UBYTE *)title;
  181.             textreq.es_TextFormat = (UBYTE *)text;
  182.             textreq.es_GadgetFormat = (UBYTE *)gadgets;
  183.  
  184.             rc = EasyRequestArgs(win, &textreq, NULL, ap);
  185.  
  186.             }
  187.  
  188.         }
  189.  
  190.     va_end(ap);
  191.  
  192.     return(rc);
  193. }
  194.  
  195. /*
  196.  *  myopenlibrary(): same as OpenLibrary(), but opens a retry-requester
  197.  *                   if OpenLibrary() fails, to give the user a chance to
  198.  *                   copy the library to libs: and retry
  199.  *                   requires request(), see above
  200.  */
  201. struct Library __regargs *myopenlibrary(char *name, unsigned long version)
  202. {
  203.     struct Library *libptr;
  204.     long ok = TRUE;
  205.  
  206.     do {
  207.         if (!(libptr = OpenLibrary((UBYTE *)name, version))) {
  208.             ok = request(MSG_ATTENTION, RETRY_GADGETS, MSG_ERROR_LIBRARY, name, version);
  209.             }
  210.         } while (!libptr && ok);
  211.  
  212.     return(libptr);
  213. }
  214.  
  215. void __main(char *line)
  216. {
  217.     long rc = RETURN_FAIL;
  218.     struct DiskObject *diskobj = NULL;
  219.     struct Library *IconBase = NULL;
  220.     struct RDArgs *args = NULL;
  221.     struct Screen *scr;
  222.     struct Task *mytask;
  223.     struct Window *win;
  224.     char startpri;
  225.     #define WIDTH_OF_CLOSE_GADGET 20
  226.     #define WIDTH_OF_DEPTH_GADGET 23
  227.     #define P_WA_Left       0
  228.     #define P_WA_Top        1
  229.     #define P_WA_Width      2
  230.     #define P_WA_Height     3
  231.     #define P_WA_PubScreen  6
  232.     static struct TagItem mywindowtags[] = {
  233.         WA_Left,        0l,
  234.         WA_Top,         0l,
  235.         WA_Width,       0l,
  236.         WA_Height,      0l,
  237.         WA_IDCMP,       IDCMP_CLOSEWINDOW,
  238.         WA_Flags,       WFLG_DRAGBAR | WFLG_CLOSEGADGET | WFLG_SMART_REFRESH | WFLG_RMBTRAP,
  239.         WA_PubScreen,   0l,
  240.         WA_ScreenTitle, (ULONG)&version[TITLE_OFFSET],
  241.         TAG_END
  242.         };
  243.  
  244.     if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37l)) {
  245.  
  246.         unsigned long left = -1;
  247.         unsigned long top = -1;
  248.  
  249.         if (!WBenchMsg) {
  250.             /*
  251.              *  started from Shell
  252.              *
  253.              *  change name of program
  254.              */
  255.             SetProgramName(PROGRAMTITLE);
  256.             /*
  257.              *  display banner
  258.              */
  259.             PutStr(&version[TITLE_OFFSET]); PutStr("\n");
  260.             /*
  261.              *  parse command line
  262.              */
  263.             if (args = ReadArgs((UBYTE *)TEMPLATE, options, NULL)) {
  264.                 if (options[OPTN_UPDATESECONDS]) updateseconds = *((long *)options[OPTN_UPDATESECONDS]);
  265.                 if (options[OPTN_UPDATEMICROS]) updatemicros = *((long *)options[OPTN_UPDATEMICROS]);
  266.                 if (options[OPTN_TOP]) top = *((long *)options[OPTN_TOP]);
  267.                 if (options[OPTN_LEFT]) left = *((long *)options[OPTN_LEFT]);
  268.                 if (options[OPTN_PRIORITY]) priority = *((long *)options[OPTN_PRIORITY]);
  269.                 if (options[OPTN_SPACE]) space = *((long *)options[OPTN_SPACE]);
  270.                 rc = 0;
  271.                 }
  272.             else {
  273.                 /*
  274.                  *  error parsing args
  275.                  */
  276.                 PrintFault(IoErr(), NULL);
  277.                 }
  278.             }
  279.  
  280.         else if (IconBase = myopenlibrary(ICONNAME, 37l)) {
  281.  
  282.             BPTR olddir = -1l;
  283.             char **tooltypesarray;
  284.             char *tooltype;
  285.             struct WBArg *wbarg;
  286.  
  287.             if (wbarg = &(WBenchMsg->sm_ArgList)[WBenchMsg->sm_NumArgs - 1l]) {
  288.  
  289.                 if (wbarg->wa_Name) {
  290.  
  291.                     if (wbarg->wa_Lock) olddir = CurrentDir(wbarg->wa_Lock);
  292.  
  293.                     if (diskobj = GetDiskObject(wbarg->wa_Name)) {
  294.  
  295.                         tooltypesarray = diskobj->do_ToolTypes;
  296.  
  297.                         if (tooltype = FindToolType(tooltypesarray, OPTION_FORMAT)) FORMAT = (long)tooltype;
  298.                         if (tooltype = FindToolType(tooltypesarray, OPTION_UPDATESECONDS)) updateseconds = atol(tooltype);
  299.                         if (tooltype = FindToolType(tooltypesarray, OPTION_UPDATEMICROS)) updatemicros = atol(tooltype);
  300.                         if (FindToolType(tooltypesarray, OPTION_WINDOWTOFRONT)) WINDOWTOFRONT = TRUE;
  301.                         if (tooltype = FindToolType(tooltypesarray, OPTION_LEFT)) left = atol(tooltype);
  302.                         if (tooltype = FindToolType(tooltypesarray, OPTION_TOP)) top = atol(tooltype);
  303.                         if (tooltype = FindToolType(tooltypesarray, OPTION_PRIORITY)) priority = atol(tooltype);
  304.                         if (tooltype = FindToolType(tooltypesarray, OPTION_SPACE)) space = atol(tooltype);
  305.                         if (tooltype = FindToolType(tooltypesarray, OPTION_PUBSCREEN)) PUBSCREEN = (long)tooltype;
  306.                         rc = 0;
  307.  
  308.                         } /* if diskobj */
  309.  
  310.                     if (olddir != -1l) CurrentDir(olddir);
  311.  
  312.                     } /* if wbarg->wa_Name */
  313.  
  314.                 } /* if wbarg */
  315.  
  316.             } /* if WBenchMsg && IconBase */
  317.  
  318.         if (!rc && !CheckSignal(SIGBREAKF_CTRL_C) && (GfxBase = myopenlibrary("graphics.library", 37l))) {
  319.  
  320.             rc = RETURN_FAIL;
  321.  
  322.             if (mytask = FindTask(NULL)) {
  323.  
  324.                 if (LocaleBase = myopenlibrary("locale.library", 38l)) {
  325.  
  326.                     if (locale = OpenLocale(NULL)) {
  327.  
  328.                         if (!FORMAT) FORMAT = (long)locale->loc_ShortDateTimeFormat;
  329.  
  330.                         if (timerport = CreateMsgPort()) {
  331.  
  332.                             if (timereq = CreateIORequest(timerport, sizeof(struct timerequest))) {
  333.  
  334.                                 if (!OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)timereq, 0l)) {
  335.  
  336.                                     if (scr = LockPubScreen((UBYTE *)PUBSCREEN)) {
  337.  
  338.                                         DateStamp(&datestamp);
  339.                                         bufferpos = 0;
  340.                                         FormatDate(locale, (STRPTR)FORMAT, &datestamp, &putcharhook);
  341.  
  342.                                         mywindowtags[P_WA_Width].ti_Data = (ULONG)(TextLength(&scr->RastPort, buffer, strlen(buffer)) + WIDTH_OF_CLOSE_GADGET + space);
  343.                                         if (left != -1) mywindowtags[P_WA_Left].ti_Data = left;
  344.                                         else mywindowtags[P_WA_Left].ti_Data = (ULONG)(scr->Width - mywindowtags[P_WA_Width].ti_Data - WIDTH_OF_DEPTH_GADGET);
  345.                                         if (top != -1) mywindowtags[P_WA_Top].ti_Data = top;
  346.                                         mywindowtags[P_WA_Height].ti_Data = (ULONG)(scr->BarHeight + 1);
  347.                                         mywindowtags[P_WA_PubScreen].ti_Data = (ULONG)scr;
  348.  
  349.                                         if (win = OpenWindowTagList(NULL, mywindowtags)) {
  350.  
  351.                                             timereq->tr_node.io_Command = TR_ADDREQUEST;
  352.                                             timereq->tr_time.tv_secs = 0l;
  353.                                             timereq->tr_time.tv_micro = 10l;
  354.                                             SendIO(&(timereq->tr_node));
  355.  
  356.                                             startpri = SetTaskPri(mytask, priority);
  357.  
  358.                                             getmessages(win);
  359.  
  360.                                             SetTaskPri(mytask, (long)startpri);
  361.  
  362.                                             CloseWindow(win);
  363.  
  364.                                             rc = 0;
  365.  
  366.                                             }
  367.  
  368.                                         UnlockPubScreen(NULL, scr);
  369.  
  370.                                         }
  371.  
  372.                                     CloseDevice((struct IORequest *)timereq);
  373.  
  374.                                     } /* if OpenDevice() */
  375.  
  376.                                 else request(MSG_ATTENTION, RESUME_GADGETS, MSG_ERROR_LIBRARY, TIMERNAME, 0);
  377.  
  378.                                 DeleteIORequest(timereq);
  379.  
  380.                                 } /* if timereq = CreateIORequest() */
  381.  
  382.                             DeleteMsgPort((struct MsgPort *)timerport);
  383.  
  384.                             } /* if timerport */
  385.  
  386.                         else request(MSG_ATTENTION, RESUME_GADGETS, MSG_ERROR_OPENPORT);
  387.  
  388.                         CloseLocale(locale);
  389.  
  390.                         }
  391.  
  392.                     CloseLibrary(LocaleBase);
  393.  
  394.                     }
  395.  
  396.                 } /* if mytask */
  397.  
  398.             CloseLibrary(GfxBase);
  399.  
  400.             } /* if GfxBase */
  401.  
  402.         if (!WBenchMsg) {
  403.             if (args) FreeArgs(args);
  404.             }
  405.         else {
  406.             if (diskobj) FreeDiskObject(diskobj);
  407.             if (IconBase) CloseLibrary(IconBase);
  408.             }
  409.  
  410.         CloseLibrary((struct Library *)IntuitionBase);
  411.  
  412.         } /* if IntutionBase */
  413.  
  414.     __exit(rc);
  415. }
  416.  
  417. void __saveds __asm putcharfunc(register __a0 struct Hook *h, register __a2 void *object, register __a1 char c)
  418. {
  419.     if (bufferpos < BUFFERSIZE) ((char *)h->h_Data)[bufferpos++] = c;
  420. }
  421.  
  422. void __regargs getmessages(struct Window *win)
  423. {
  424.     struct IntuiMessage *msg;
  425.     unsigned long sigreceived;
  426.     unsigned long idcmpsigflag = 1 << win->UserPort->mp_SigBit;
  427.     unsigned long timersigflag = 1 << timerport->mp_SigBit;
  428.     unsigned long sigstowaitfor = SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F | idcmpsigflag | timersigflag;
  429.     unsigned short quit = FALSE;
  430.  
  431.     while (!quit) {
  432.  
  433.         sigreceived = Wait(sigstowaitfor);
  434.  
  435.         if (sigreceived & timersigflag) {
  436.             /*
  437.              *  signal at timerport
  438.              */
  439.             if (GetMsg(timerport) == (struct Message *)timereq) {
  440.                 /*
  441.                  *  arrived any message ?
  442.                  */
  443.                 timereq->tr_time.tv_secs = updateseconds;
  444.                 timereq->tr_time.tv_micro = updatemicros;
  445.                 SendIO(&(timereq->tr_node));
  446.  
  447.                 bufferpos = 0;
  448.                 DateStamp(&datestamp);
  449.                 FormatDate(locale, (STRPTR)FORMAT, &datestamp, &putcharhook);
  450.                 SetWindowTitles(win, buffer, (UBYTE*)~0);
  451.                 if (WINDOWTOFRONT && (IntuitionBase->FirstScreen == win->WScreen)) WindowToFront(win);
  452.                 }
  453.             }
  454.  
  455.         if (sigreceived & idcmpsigflag) {
  456.  
  457.             while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)) && !quit) {
  458.                 /*
  459.                  *  check and free message
  460.                  */
  461.                 if (msg->Class == CLOSEWINDOW) quit = TRUE;
  462.                 ReplyMsg((struct Message *)msg);
  463.                 } /* while msg */
  464.  
  465.             }
  466.  
  467.         if (sigreceived & SIGBREAKF_CTRL_C) quit = TRUE;
  468.         if (sigreceived & SIGBREAKF_CTRL_F) WindowToFront(win);
  469.  
  470.         } /* while !quit */
  471.  
  472.     /*
  473.      *  cancel pending IORequest
  474.      */
  475.     AbortIO(&(timereq->tr_node));
  476.     WaitIO((struct IORequest *)timereq);
  477.  
  478. }
  479.